package com.sinodata.bsm.cicp.collector.environment;

import java.util.LinkedList;
import java.util.List;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.exception.CollectorException;

/**
 *
 * @author 友联创新 hehy
 * @date Dec 22, 2008
 */
public class EmersonParadigmUPS {
    public static final int baudRate = 9600;
    public static final int dataBits = 8;
    public static final int stopBits = 1;
    public static final int parity = 0;
    public static Logger logger = Logger.getLogger(EmersonParadigmUPS.class);

    /**
     * 获取设备地址命令 此命令只能适用于点到点的通信方式
     *
     * @return
     * @throws CollectorException
     */
    public byte[] getAdrCmd() throws CollectorException {
        byte VER = 0x0;// 通信协议版本号
        byte ADR = 0x0;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x2A;// 控制标识码（设备类型描述）
        byte CID2 = 0x50;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     * 解析获取设备地址命令命令返回
     *
     * @param resp
     * @return
     */
    public static byte analyseAdrResponse(byte[] resp) {
        return ElectriProtocol.unite2ASCII(resp[3], resp[4]);
    }

    /**
     * 获取通信协议版本号
     *
     * @return
     */
    public static byte[] getverCmd() throws CollectorException {
        byte VER = 0x0;// 通信协议版本号
        byte ADR = 0x0;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x2A;// 控制标识码（设备类型描述）
        byte CID2 = 0x4F;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     * 获取通信协议版本号
     *
     * @param resp
     * @return
     */
    public static byte analyseVerResponse(byte[] resp) {
        return ElectriProtocol.unite2ASCII(resp[1], resp[2]);
    }

    /**
     * 获取模拟量量化数据（浮点数）
     */
    public static byte[] analogSignalsCmd(byte ver, byte adr) throws CollectorException {
        byte VER = ver;// 通信协议版本号
        byte ADR = adr;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x2A;// 控制标识码（设备类型描述）
        byte CID2 = 0x41;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     * 分析获取模拟量量化后数据命令返回
     */
    public static float[] analyseAnalogSignalsResponse(byte[] resp) throws CollectorException {
        byte[] infoBytes = ElectriProtocol.getInfoBytes(resp);
        // 交流电入项电压A
        float inUA = ElectriProtocol.mergeFloat(infoBytes[0], infoBytes[1], infoBytes[2], infoBytes[3]);
        // 交流电入项电压B
        float inUB = ElectriProtocol.mergeFloat(infoBytes[4], infoBytes[5], infoBytes[6], infoBytes[7]);
        // 交流电入项电压C
        float inUC = ElectriProtocol.mergeFloat(infoBytes[8], infoBytes[9], infoBytes[10], infoBytes[11]);
        // -------------------------------------
        // 交流电出项电压A
        float outUA = ElectriProtocol.mergeFloat(infoBytes[12], infoBytes[13], infoBytes[14], infoBytes[15]);
        // 交流电出项电压B
        float outUB = ElectriProtocol.mergeFloat(infoBytes[16], infoBytes[17], infoBytes[18], infoBytes[19]);
        // 交流电出项电压C
        float outUC = ElectriProtocol.mergeFloat(infoBytes[20], infoBytes[21], infoBytes[22], infoBytes[23]);
        // ------------------------------------------
        // 交流电出项电流A
        float outIA = ElectriProtocol.mergeFloat(infoBytes[24], infoBytes[25], infoBytes[26], infoBytes[27]);
        // 交流电出项电流B
        float outIB = ElectriProtocol.mergeFloat(infoBytes[28], infoBytes[29], infoBytes[30], infoBytes[31]);
        // 交流电出项电流C
        float outIC = ElectriProtocol.mergeFloat(infoBytes[32], infoBytes[33], infoBytes[34], infoBytes[35]);
        // -------------------------------------------
        // 电池电压
        float innerU = ElectriProtocol.mergeFloat(infoBytes[36], infoBytes[37], infoBytes[38], infoBytes[39]);
        // 输出频率
        float outHZ = ElectriProtocol.mergeFloat(infoBytes[40], infoBytes[41], infoBytes[42], infoBytes[43]);

        return new float[] { inUA, inUB, inUC, outUA, outUB, outUC, outIA, outIB, outIC, innerU, outHZ };
    }

    /**
     * 获取开关输入状态
     *
     * @param adr
     * @return
     */
    public static byte[] switchStatusCmd(byte ver, byte adr) throws CollectorException {
        byte VER = ver;// 通信协议版本号
        byte ADR = adr;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x2A;// 控制标识码（设备类型描述）
        byte CID2 = 0x43;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, null);
        return cmd;
    }

    /**
     * 分析开关量返回
     *
     * @param resp
     * @return
     */
    public static String[] analyseSwitchResponse(byte[] resp) throws CollectorException {
        byte[] infoBytes = ElectriProtocol.getInfoBytes(resp);
        if (infoBytes.length != 13) {
            logger.error("format error");
            return null;
        }
        // 供电方式
        String supplyMod = "";
        if (infoBytes[0] == (byte) 0x01) {
            supplyMod = "UPS供电";
        } else if (infoBytes[0] == (byte) 0x02) {
            supplyMod = "旁路供电";
        } else if (infoBytes[0] == (byte) 0xE9) {
            supplyMod = "均不供电";
        }
        // 充电方式 均充/浮充（正组）
        String chargeMod = "";
        if (infoBytes[4] == (byte) 0xE0) {
            chargeMod = "浮充";
        } else if (infoBytes[4] == (byte) 0xE1) {
            chargeMod = "均充";
        } else if (infoBytes[4] == (byte) 0xE2) {
            chargeMod = "非充电状态";
        }

        // 开机/关机
        String upOrDown = "";
        if (infoBytes[5] == (byte) 0xE0) {
            upOrDown = "已关机";
        } else if (infoBytes[5] == (byte) 0xE1) {
            upOrDown = "已开机";
        }

        // UPS供电
        String upsSupply = "";
        if (infoBytes[6] == (byte) 0xE0) {
            upsSupply = "主路逆变供电";
        } else if (infoBytes[6] == (byte) 0xE1) {
            upsSupply = "电池逆变供电";
        } else if (infoBytes[6] == (byte) 0xE2) {
            upsSupply = "联合逆变供电";
        } else if (infoBytes[6] == (byte) 0xE3) {
            upsSupply = "整流电池均不供电";
        }
        // 发电机接入
        String generator = "";
        if (infoBytes[7] == (byte) 0xE0) {
            generator = "发电机接入";
        } else if (infoBytes[7] == (byte) 0xE1) {
            generator = "发电机没接入";
        }
        // 输入空开状态
        String inAirSwitch = "";
        if (infoBytes[8] == (byte) 0xE0) {
            inAirSwitch = "断开状态";
        } else if (infoBytes[8] == (byte) 0xE1) {
            inAirSwitch = "闭合状态";
        }
        // 维修旁路空开状态
        String repairAirSwitch = "";
        if (infoBytes[9] == (byte) 0xE0) {
            repairAirSwitch = "断开状态";
        } else if (infoBytes[9] == (byte) 0xE1) {
            repairAirSwitch = "闭合状态";
        }
        // 旁路空开状态
        String sideAirSwitch = "";
        if (infoBytes[10] == (byte) 0xE0) {
            sideAirSwitch = "断开状态";
        } else if (infoBytes[10] == (byte) 0xE1) {
            sideAirSwitch = "闭合状态";
        }

        // 输出空开状态
        String outAirSwitch = "";
        if (infoBytes[11] == (byte) 0xE0) {
            outAirSwitch = "断开状态";
        } else if (infoBytes[11] == (byte) 0xE1) {
            outAirSwitch = "闭合状态";
        }

        // 旋转空开状态
        String rollAirSwitch = "";
        if (infoBytes[12] == (byte) 0xE0) {
            rollAirSwitch = "关闭状态";
        } else if (infoBytes[12] == (byte) 0xE1) {
            rollAirSwitch = "测试状态";
        } else if (infoBytes[12] == (byte) 0xE2) {
            rollAirSwitch = "正常状态";
        } else if (infoBytes[12] == (byte) 0xE3) {
            rollAirSwitch = "旁路状态";
        } else if (infoBytes[12] == (byte) 0xE4) {
            rollAirSwitch = "维修状态";
        }

        // 并机系统供电状态
        String parallelStats = "";
        if (infoBytes[13] == (byte) 0xE0) {
            parallelStats = "主路逆变供电";
        } else if (infoBytes[13] == (byte) 0xE1) {
            parallelStats = "电池逆变供电";
        } else if (infoBytes[13] == (byte) 0xE2) {
            parallelStats = "旁路供电";
        } else if (infoBytes[13] == (byte) 0xE3) {
            parallelStats = "均不供电";
        }
        return new String[] { supplyMod, chargeMod, upOrDown, upsSupply, generator, inAirSwitch, repairAirSwitch, sideAirSwitch, outAirSwitch, rollAirSwitch, parallelStats };
    }

    /**
     * 获取报警状态
     *
     * @param ver
     * @param adr
     * @return
     * @throws CollectorException
     */
    public static byte[] alarmCmd(byte ver, byte adr) throws CollectorException {
        byte VER = ver;// 通信协议版本号
        byte ADR = adr;// 设备地址描述（1～254，0、255保留）
        byte CID1 = 0x2A;// 控制标识码（设备类型描述）
        byte CID2 = (byte) 0x44;// 命令信息:控制标识码（数据或动作类型描述） 响应信息:返回码RTN
        byte[] info = new byte[] { 0x01 };
        byte[] cmd = ElectriProtocol.getCommand(VER, ADR, CID1, CID2, info);
        return cmd;
    }

    public static String[] alarmTable = new String[65];
    static {
        alarmTable[0] = "逆变器同步/不同步      ";
        alarmTable[1] = "主路电压异常           ";
        alarmTable[2] = "整流器                 ";
        alarmTable[3] = "逆变器                 ";
        alarmTable[4] = "旁路情况（电压或频率） ";
        alarmTable[5] = "蓄电池总电压状态       ";
        alarmTable[6] = "标示电池数量m          ";
        alarmTable[7] = "用户自定义告警数量为57 ";
        alarmTable[8] = "主路频率异常           ";
        alarmTable[9] = "平衡电感过温           ";
        alarmTable[10] = "输入电感过温           ";
        alarmTable[11] = "整流器过温             ";
        alarmTable[12] = "平衡电路故障           ";
        alarmTable[13] = "平衡电路过流           ";
        alarmTable[14] = "电池接触器故障         ";
        alarmTable[15] = "电池变换器故障         ";
        alarmTable[16] = "电池变换器过流         ";
        alarmTable[17] = "电池变换器过温         ";
        alarmTable[18] = "主路熔丝断             ";
        alarmTable[19] = "辅助电源1掉电          ";
        alarmTable[20] = "主路相序反             ";
        alarmTable[21] = "整流器过流             ";
        alarmTable[22] = "软启动失败             ";
        alarmTable[23] = "旁路过流故障           ";
        alarmTable[24] = "逆变电感过温           ";
        alarmTable[25] = "逆变器过温             ";
        alarmTable[26] = "风扇故障               ";
        alarmTable[27] = "逆变晶闸管故障         ";
        alarmTable[28] = "旁路晶闸管故障         ";
        alarmTable[29] = "用户操作错误           ";
        alarmTable[30] = "输出熔丝断             ";
        alarmTable[31] = "辅助电源2掉电          ";
        alarmTable[32] = "单机输出过载           ";
        alarmTable[33] = "并机系统过载           ";
        alarmTable[34] = "单机过载超时           ";
        alarmTable[35] = "旁路异常关机           ";
        alarmTable[36] = "交流输出过压           ";
        alarmTable[37] = "逆变器过流             ";
        alarmTable[38] = "旁路相序反             ";
        alarmTable[39] = "负载冲击转旁路         ";
        alarmTable[40] = "旁路切换次数限制       ";
        alarmTable[41] = "并机均流故障           ";
        alarmTable[42] = "母线异常关机           ";
        alarmTable[43] = "邻机请求转旁路         ";
        alarmTable[44] = "并机板故障             ";
        alarmTable[45] = "直流母线过压故障       ";
        alarmTable[46] = "并机线连接故障         ";
        alarmTable[47] = "环境温度过高           ";
        alarmTable[48] = "整流通讯故障           ";
        alarmTable[49] = "逆变通讯故障           ";
        alarmTable[50] = "并机通讯故障           ";
        alarmTable[51] = "输出直流分量过大故障   ";
        alarmTable[52] = "并机系统电池预告警故障 ";
        alarmTable[53] = "输入缺零故障           ";
        alarmTable[54] = "逆变接触器故障         ";
        alarmTable[55] = "充电器故障             ";
        alarmTable[56] = "蓄电池寿命情况         ";
        alarmTable[57] = "紧急关机               ";
        alarmTable[58] = "电池温度过高           ";
        alarmTable[59] = "BCB接入情况            ";
        alarmTable[60] = "电池接地故障           ";
        alarmTable[61] = "LBS异常                ";
        alarmTable[62] = "输入接触器故障         ";
        alarmTable[63] = "接触器电源板1故障      ";
        alarmTable[64] = "接触器电源板2故障      ";

    }

    /**
     * 解析报警命令返回
     *
     * @param resp
     * @return
     * @throws CollectorException
     */
    public static List<String> analyseAlarmResponse(byte[] resp) throws CollectorException {
        List<String> ret = new LinkedList<String>();
        byte[] infoBytes = ElectriProtocol.getInfoBytes(resp);
        if (infoBytes.length != 65) {
            logger.error("format error");
            return null;
        }
        for (int i = 0; i < infoBytes.length; i++) {
            if (infoBytes[i] != 0x0) {
                ret.add(alarmTable[i]);
            }
        }
        return ret;
    }
}
